package com.loveyukari.service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.loveyukari.dao.BlackIpDao;

import net.sf.json.JSONObject;

/**
*
*yangshaohua
*2017年8月9日下午12:49:34
**/
@Service
public class IpService {
	
	@Autowired
	private BlackIpDao blackIpDao;
	
	private Logger log = LoggerFactory.getLogger("IpInfo");
	
	private static Set<String> whitePath = new HashSet<String>();
	static{
		whitePath.add("/admin/draw/ticket/getResult");
	}

	private static Set<String> whiteIp = new HashSet<String>();
	static{
		whitePath.add("47.98.98.88");
	}
	
	private Map<String,Integer> ipReqCountMap = new HashMap<String,Integer>();

	private Set<String> blackIpSet = new HashSet<String>();
	
	private boolean loginFlag = false;
	
	public boolean isBlackIp(String ip){
		return blackIpSet.contains(ip);
	}
	
	public boolean isNotLogin(){
		return loginFlag;
	}
	
	public void setLogigFlag(boolean flag){
		this.loginFlag = flag;
	}
	public void recordIPRequest(String ip,String requestPath,JSONObject params){
		String key = ip+","+requestPath;
		Integer count = this.ipReqCountMap.get(key);
		if (count == null){
			count = 0;
			log.info(key+";"+params);
		}
		count++;
		this.ipReqCountMap.put(key, count);
	}
	
	private Integer singleRequstMaxCount = 150;
	private Integer allRequestMaxCount = 500;
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
	private String time = sdf.format(new Date());
	@Scheduled(cron="15 * * * * *")
	public void banIp(){
		Map<String,Integer> map = this.ipReqCountMap;
		this.ipReqCountMap = new HashMap<String, Integer>();
		if (time.equals(sdf.format(DateUtils.addMinutes(new Date(), -1)))){
			Set<String> keySet = map.keySet();
			Map<String,Integer> ipCountMap = new HashMap<String, Integer>();
			int loginCount = 0;
			for (String key : keySet) {
				String[] split = key.split(",");
				String ip = split[0];
				String request = split[1];
				Integer count = map.get(key);
				if (count > singleRequstMaxCount && !whitePath.contains(request)){
					blackIpDao.insertBlackIp(ip);
				}
				JSONObject logInfo = new JSONObject();
				logInfo.put("type", "ipReqCount");
				logInfo.put("ip", ip);
				logInfo.put("request", request);
				logInfo.put("count", count);
				log.info(logInfo.toString());
				Integer ipCount = ipCountMap.get(ip);
				if (ipCount == null){
					ipCount = 0;
				}
				if (!whitePath.contains(request)){
					ipCount += count;
				}
				ipCountMap.put(ip, ipCount);
				if (this.isLoginRequest(request)){
					loginCount += count;
				}
			}
			Set<String> ipKeySet = ipCountMap.keySet();
			for (String ipKey : ipKeySet) {
				Integer ipCount = ipCountMap.get(ipKey);
				if (ipCount > allRequestMaxCount  && !whitePath.contains(ipKey)){
					blackIpDao.insertBlackIp(ipKey);
				}
				JSONObject logInfo = new JSONObject();
				logInfo.put("type", "ipCount");
				logInfo.put("ip", ipKey);
				logInfo.put("count", ipCount);
				log.info(logInfo.toString());
			}
			if (loginCount > 100){
				this.loginFlag = true;
			}
		}
		time = sdf.format(new Date());
		this.reload();
	}
	
	@PostConstruct
	public void init(){
		List<String> list = blackIpDao.selectBlackIpAll();
		blackIpSet.addAll(list);
	}
	
	public void reload(){
		List<String> list = blackIpDao.selectBlackIpAll();
		HashSet<String> set = new HashSet<String>(list);
		blackIpSet = set;
	}
	
	public boolean isLoginRequest(String request){
		return StringUtils.startsWith(request, "/login");
	}
	
}
